package com.rzjm.api.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.rzjm.api.entity.*;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.encoders.Hex;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 *  电焊机省平台对接工具类
 * @创建者：zhouwei
 * @创建时间：2024-05-20
 * @描述：
 */
public class ElectricWeldingUtil {

    //key必须是16字节，即128位
    final static String key = "sm4demo123456789";
    //指明加密算法和秘钥
    static SymmetricCrypto sm4 = new SymmetricCrypto("SM4/ECB/PKCS5Padding", key.getBytes());

    /**
     *  测试请求域名地址
     */
//    private static String webSiteUrl = "https://sdhhdp.yjt.shandong.gov.cn:9444/weld-standard/hzfj-weld-join";


    /**
     *  测试请求域名地址
     */
    private static String webSiteUrl = "https://sdhh.yjt.shandong.gov.cn:9443/weld-standard/hzfj-weld-join";


    /**
     *  企业上报同步接口
     * @param companyList
     * @return
     */
    public static String uploadCompany(List<Shop> companyList, Platform platform,String addOrUpdate){
        String ret = "";

        List<JSONObject> dataList = new ArrayList<>();
        for (Shop company : companyList){

            JSONObject jsonObject = new JSONObject();
            jsonObject.set("dataId", company.getId());//唯一表示
            jsonObject.set("name", company.getShopName());//企业名称
            jsonObject.set("type", "1");//企业类型
            jsonObject.set("creditCode", company.getSocialCode());//统一代码
            jsonObject.set("areaCode",  company.getAreaCode());//行政区划
            jsonObject.set("address", company.getAddress());//生产经营地址
            jsonObject.set("userName", company.getHeadman());//联系人
            jsonObject.set("phone", company.getTelphone());//联系人电话
            jsonObject.set("establishDate", company.getBuildDate());//企业成立日期
            jsonObject.set("legalPerson", company.getLegalPerson());//法人
            jsonObject.set("legalPhone", company.getLegalPhone());//法人联系方式
            jsonObject.set("domain", company.getCompanyType());//所属领域
            jsonObject.set("operateType", addOrUpdate);//操作类型 I:新增  U:修改  D: 删除
            jsonObject.set("operateTime", DateUtil.getTime());//操作时间

            dataList.add(jsonObject);
        }

        JSONObject requestData = new JSONObject();


        String dataJson = JSON.toJSONString(dataList);
        System.out.println("数据：" + dataJson);
//        String data = BcSm4Util.encrypt(dataJson, platform.getSecretKey());
        // 加密
        try {
            byte[] encrypted = Sm4Utils.encrypt(platform.getSecretKey(), dataJson);
            System.out.println("加密后: " + Sm4Utils.bytesToHex(encrypted));
            String data = Sm4Utils.bytesToHex(encrypted);
            requestData.set("data", data);
            requestData.set("appId", platform.getAppId());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        System.out.println("企业上报请求参数：" + requestData.toString());

        String url = webSiteUrl + "/weldSync/apis/deviceUnit/provider";
        try {
            String resp = OkHttpClientUtil.getInstance().postJson(url, requestData.toString());
            System.out.println("企业上报响应：" + resp);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return ret;
    }

    /**
     *  焊机上报同步接口
     * @param deviceList
     * @return
     */
    public static String uploadDevice(Shop shop, List<DeviceWelding> deviceList, Platform platform){
        String ret = "";
        List<JSONObject> dataList = new ArrayList<>();
        for (DeviceWelding device : deviceList){
            JSONObject jsonObject = new JSONObject();
            jsonObject.set("deviceCode", device.getProvNo());//唯一标识
            jsonObject.set("deviceType", "12");//电焊设备类型
            jsonObject.set("manufactureName", shop.getShopName());//电焊机生产企业
            jsonObject.set("creditCode", shop.getSocialCode());//企业编码
            jsonObject.set("areaCode", shop.getAreaCode());//行政区划
            if(StrUtil.isNotEmpty(device.getDateOfManufacture())){
                if(device.getDateOfManufacture().contains("00:00:00")){
                    jsonObject.set("produceDate", device.getDateOfManufacture());//生产日期
                }else{
                    jsonObject.set("produceDate", device.getDateOfManufacture() + " 00:00:00");//生产日期
                }
            }else{
                jsonObject.set("produceDate", "2023-10-20 00:00:00");//生产日期
            }
            jsonObject.set("voltage", "380V");//电压
            jsonObject.set("netMode4G", 1);//联网模式4G
            jsonObject.set("netMode5G", 0);//联网模式5G
            jsonObject.set("netModeBt", 0);//蓝牙联网模式
            jsonObject.set("riskLevel", "2");//管控级别
            jsonObject.set("operateType", "I");//操作类型 I:新增  U:修改  D: 删除
            jsonObject.set("operateTime", DateUtil.getTime());//操作时间
            dataList.add(jsonObject);
        }
        String dataJson = JSON.toJSONString(dataList);
        System.out.println("数据：" + dataJson);
        JSONObject requestData = new JSONObject();
        try {
            byte[] encrypted = Sm4Utils.encrypt(platform.getSecretKey(), dataJson);
            System.out.println("加密后: " + Sm4Utils.bytesToHex(encrypted));
            String data = Sm4Utils.bytesToHex(encrypted);
            requestData.set("data", data);
            requestData.set("appId", platform.getAppId());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        System.out.println("电焊机上报请求参数：" + requestData.toString());
        String url = webSiteUrl + "/weldSync/apis/deviceInfo/provider";
        try {
            String resp = OkHttpClientUtil.getInstance().postJson(url, requestData.toString());
            System.out.println("电焊机上报响应：" + resp);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return ret;
    }

    /**
     *  焊机智能终端上报同步
     * @param deviceList
     * @return
     */
    public static String uploadDeviceIot(Shop shop, List<DeviceWelding> deviceList, Platform platform){
        String ret = "";

        List<JSONObject> dataList = new ArrayList<>();
        for (DeviceWelding device : deviceList){

            JSONObject jsonObject = new JSONObject();
            jsonObject.set("moduleCode", device.getProvNo());//设备编号
            jsonObject.set("moduleNode", "12");//设备型号
            jsonObject.set("moduleSupplier", shop.getShopName());//终端设备厂家
            jsonObject.set("moduleSupplierCode", device.getProvNo());//设备厂家编码
            if(StrUtil.isNotEmpty(device.getDateOfManufacture())){
                if(device.getDateOfManufacture().contains("00:00:00")){
                    jsonObject.set("moduleSupplierDate", device.getDateOfManufacture());//生产日期
                }else{
                    jsonObject.set("moduleSupplierDate", device.getDateOfManufacture() + " 00:00:00");//生产日期
                }
            }else{
                jsonObject.set("moduleSupplierDate", "2023-10-20 00:00:00");//生产日期
            }
            jsonObject.set("installDate", "2024-04-22 00:00:00");//安装时间
            jsonObject.set("deviceCode", device.getProvNo());//关联设备编码
            jsonObject.set("operateType", "I");//操作类型 I:新增  U:修改  D: 删除
            jsonObject.set("operateTime", DateUtil.getTime());//操作时间

            dataList.add(jsonObject);
        }

        String dataJson = JSON.toJSONString(dataList);
        System.out.println("数据：" + dataJson);

        JSONObject requestData = new JSONObject();
        try {
            byte[] encrypted = Sm4Utils.encrypt(platform.getSecretKey(), dataJson);
            System.out.println("加密后: " + Sm4Utils.bytesToHex(encrypted));
            String data = Sm4Utils.bytesToHex(encrypted);
            requestData.set("data", data);
            requestData.set("appId", platform.getAppId());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        System.out.println("焊机智能终端上报同步请求参数：" + requestData.toString());
        String url = webSiteUrl + "/weldSync/apis/loTInfo/provider";
        try {
            String resp = OkHttpClientUtil.getInstance().postJson(url, requestData.toString());
            System.out.println("焊机智能终端上报同步响应：" + resp);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return ret;
    }

    /**
     *  焊工上报同步
     * @param shop
     * @param sysUserList
     * @return
     */
    public static String uploadOperationInfo(Shop shop, List<SysUser> sysUserList, Platform platform){
        String ret = "";

        List<JSONObject> dataList = new ArrayList<>();
        for (SysUser sysUser : sysUserList){
            JSONObject jsonObject = new JSONObject();
            jsonObject.set("dataId", sysUser.getUserId());//唯一标识
            jsonObject.set("name", sysUser.getName());//姓名
            jsonObject.set("cardType", "99");//证件类型
            jsonObject.set("cardNumber", sysUser.getCertificateNum());//证件号码
            jsonObject.set("sex", "1");//性别
            jsonObject.set("phone", sysUser.getMobile());//联系方式
            jsonObject.set("creditCode", shop.getSocialCode());//工作单位统一代码
            jsonObject.set("areaCode", shop.getAreaCode());//工作单位统一代码
            jsonObject.set("operateType", "I");//操作类型 I:新增  U:修改  D: 删除
            jsonObject.set("operateTime", DateUtil.getTime());//操作时间

            dataList.add(jsonObject);
        }

        String dataJson = JSON.toJSONString(dataList);
        System.out.println("数据：" + dataJson);

        JSONObject requestData = new JSONObject();
        try {
            byte[] encrypted = Sm4Utils.encrypt(platform.getSecretKey(), dataJson);
            System.out.println("加密后: " + Sm4Utils.bytesToHex(encrypted));
            String data = Sm4Utils.bytesToHex(encrypted);
            requestData.set("data", data);
            requestData.set("appId", platform.getAppId());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        System.out.println("焊工上报同步请求参数：" + requestData.toString());
        String url = webSiteUrl + "/weldSync/apis/operationInfo/provider";
        try {
            String resp = OkHttpClientUtil.getInstance().postJson(url, requestData.toString());
            System.out.println("焊工上报同步上报响应：" + resp);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return ret;
    }

    /**
     *  特种作业操作证信息接口
     * @param shop
     * @param sysUserList
     * @return
     */
    public static String uploadCertificateInfo(Shop shop, List<SysUser> sysUserList, Platform platform, String certPath){
        String ret = "";
        List<JSONObject> dataList = new ArrayList<>();
        for (SysUser sysUser : sysUserList){
            JSONObject jsonObject = new JSONObject();
            jsonObject.set("dataId", sysUser.getCertificateNum());//唯一标识
            jsonObject.set("cardType", "99");//电焊人员证件类型
            jsonObject.set("cardNumber", sysUser.getCertificateNum());//电焊人员证件号码
            jsonObject.set("certificateName", "焊工证");//证书名称
            jsonObject.set("certificateCode", sysUser.getCertificateNum());//证书编号
            jsonObject.set("issuingAuthority", "1");//发证机关类型
            jsonObject.set("issuingAuthorityStr", sysUser.getSignOrgan());//发证机关
            jsonObject.set("dueDate", sysUser.getCertBeginTime());//证书到期日期
            jsonObject.set("checkTime", sysUser.getCertEndTime());//下此复审时间
            if(StrUtil.isNotEmpty(sysUser.getCertificateImg())){
                String path = certPath + sysUser.getCertificateImg();
                System.out.println("路径：" + path);
                String base64Str = Base64Util.getBase64ByImgPath(path);
//                System.out.println("图片base64: " + base64Str);
                // 读取图片文件到字节数组
//                Path path = new File(imagePath).toPath();
//                byte[] imageBytes = Files.readAllBytes(path);

                jsonObject.set("certificatePhoto", "data:image/jpeg;base64," + base64Str);//证书照片  base64

            }
            jsonObject.set("operateType", "I");//操作类型 I:新增  U:修改  D: 删除
            jsonObject.set("operateTime", DateUtil.getTime());//操作时间

            if(sysUser.getCertBeginTime()!= null && sysUser.getCertEndTime() != null && StrUtil.isNotEmpty(sysUser.getCertificateNum())){
                dataList.add(jsonObject);
            }

        }

        String dataJson = JSON.toJSONString(dataList);
        System.out.println("数据：" + dataJson);

        JSONObject requestData = new JSONObject();
        try {
            byte[] encrypted = Sm4Utils.encrypt(platform.getSecretKey(), dataJson);
            System.out.println("加密后: " + Sm4Utils.bytesToHex(encrypted));
            String data = Sm4Utils.bytesToHex(encrypted);
            requestData.set("data", data);
            requestData.set("appId", platform.getAppId());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        System.out.println("特种作业操作证信息请求参数：" + requestData.toString());
        String url = webSiteUrl + "/weldSync/apis/certificateInfo/provider";
        try {
            String resp = OkHttpClientUtil.getInstance().postJson(url, requestData.toString());
            System.out.println("特种作业操作证信息上报响应：" + resp);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return ret;
    }

    /**
     * 电焊机开关日志接口
     * @param shop
     * @param record
     * @return
     */
    public static String uploadDeviceLog(Shop shop, DeviceWeldingRecord record, String moduleCode, String status, SysUser sysUser, Platform platform){
        String ret = "";


        List<JSONObject> dataList = new ArrayList<>();
        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.set("dataId", record.getId());//唯一标识
        jsonObject1.set("latitude", record.getLat());//纬度
        jsonObject1.set("longitude", record.getLng());//经度
        jsonObject1.set("status", status);//作业状态 0 - 关闭  1 - 开启
        jsonObject1.set("startTime", DateUtil.getTime(record.getUseBeginTime()));//开机时间
        jsonObject1.set("endTime", DateUtil.getTime(record.getUseEndTime()));//关机时间
        jsonObject1.set("deviceCode", record.getDeviceNum());//电焊机设备编码
        jsonObject1.set("moduleCode", moduleCode);//物联终端设备编码
        jsonObject1.set("cardType", "99");//操作人员 - 证件类型
        jsonObject1.set("cardNumber", sysUser.getCertificateNum());//操作人员 - 证件号码
        jsonObject1.set("creditCode", shop.getSocialCode());//电焊机使用单位

        jsonObject1.set("operateTime", DateUtil.getTime());//操作时间
        jsonObject1.set("operateType", "I");//操作类型 I:新增  U:修改  D: 删除
        dataList.add(jsonObject1);

        String dataJson = JSON.toJSONString(dataList);
        System.out.println("数据：" + dataJson);

        JSONObject requestData = new JSONObject();
        try {
            byte[] encrypted = Sm4Utils.encrypt(platform.getSecretKey(), dataJson);
            System.out.println("加密后: " + Sm4Utils.bytesToHex(encrypted));
            String data = Sm4Utils.bytesToHex(encrypted);
            requestData.set("data", data);
            requestData.set("appId", platform.getAppId());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        System.out.println("电焊机开关日志接口请求参数：" + requestData.toString());
        String url = webSiteUrl + "/weldSync/apis/currentData/provider";
        try {
            String resp = OkHttpClientUtil.getInstance().postJson(url, requestData.toString());
            System.out.println("电焊机开关日志接口上报响应：" + resp);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return ret;
    }

    //加密为16进制，也可以加密成base64/字节数组
    public static String encryptSm4(String plaintext) {
        return sm4.encryptHex(plaintext);
    }
    //解密
    public static String decryptSm4(String ciphertext) {
        return sm4.decryptStr(ciphertext);
    }

    public static void main(String[] args) {
//        String content = "hello sm4";
//        String plain = encryptSm4(content);
//        String cipher = decryptSm4(plain);
//        System.out.println(plain + "\n" + cipher);

        try {

            // 定义原始数据
            String plaintext = "Hello, World!";
            byte[] input = plaintext.getBytes();

            // 生成密钥
            String keyHex = "a56c3f92f47d4724e484d236e9eb7fb7";
            byte[] keyData = Hex.decode(keyHex);
            SecretKey key = new SecretKeySpec(keyData, "SM4");

            // 定义初始向量（IV）
            String ivHex = "00000000000000000000000000000000";
            byte[] ivData = Hex.decode(ivHex);

            // 创建SM4算法实例
            BlockCipher engine = new SM4Engine();

            // 将SM4算法与CBC模式和PKCS7填充组合
            PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(engine));

            // 初始化加密操作
            cipher.init(true, new ParametersWithIV(new KeyParameter(keyData), ivData));

            // 执行加密操作
            byte[] ciphertext = new byte[cipher.getOutputSize(input.length)];
            int outputLen = cipher.processBytes(input, 0, input.length, ciphertext, 0);

            cipher.doFinal(ciphertext, outputLen);

            String encryptedHex = Hex.toHexString(ciphertext);
            System.out.println("Encrypted: " + encryptedHex);

            // 初始化解密操作
            cipher.init(false, new ParametersWithIV(new KeyParameter(keyData), ivData));

            // 执行解密操作
            byte[] decrypted = new byte[cipher.getOutputSize(ciphertext.length)];
            outputLen = cipher.processBytes(ciphertext, 0, ciphertext.length, decrypted, 0);
            cipher.doFinal(decrypted, outputLen);

            String decryptedText = new String(decrypted);
            System.out.println("Decrypted: " + decryptedText);

        } catch (InvalidCipherTextException e) {
            throw new RuntimeException(e);
        }

    }

}
